/**
 * 
 */
package com.dalonedrow.engine.ui.base.panel;

import com.dalonedrow.engine.systems.JOGLErrorHandler;
import com.dalonedrow.engine.systems.base.Action;
import com.dalonedrow.engine.systems.base.Condition;
import com.dalonedrow.engine.systems.base.InputEvent;
import com.dalonedrow.engine.ui.impl.Button;
import com.dalonedrow.engine.ui.impl.Label;

/**
 * @author Donald
 */
public final class ThreeStateButton extends CardPanel {
	/** the interactive button. */
	private Button		button2;
	/**
	 * a {@link Condition} that determines when the
	 * <code>ThreeStateButton</code> can stay on the 3rd state without being
	 * hovered.
	 */
	private Condition	canStayOn3;
	/**
	 * a {@link Condition} that determines when the
	 * <code>ThreeStateButton</code> is clickable. If the condition is null then
	 * the button is always clickable.
	 */
	private Condition	enabled;
	/** the flag indicating when the component is being hovered. */
	private boolean		hovering	= false;
	/** the first label displayed when the button is inactive or not hovered. */
	private Label		label1;
	/** the last label displayed when the button has been clicked. */
	private Label		label3;
	/**
	 * Creates a new instance of {@link ThreeStateButton}.
	 * @param newLabel1 the "inactive" or unselected state display
	 * @param newButton2 the clickable state display
	 * @param newLabel3 the "active" state display
	 */
	public ThreeStateButton(final Label newLabel1, final Button newButton2,
			final Label newLabel3) {
		label1 = newLabel1;
		super.addChild("1", label1);
		button2 = newButton2;
		final ThreeStateButton me = this;
		button2.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				try {
					InputEvent.getInstance().addAction(
							me, // object
							me.getClass().getMethod(
									"displayChild", 
									new Class[] { String.class }
							),
							new String[] { "3" }
							);
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
		});
		super.addChild("2", button2);
		label3 = newLabel3;
		super.addChild("3", label3);
	}
	/**
	 * Gets the interactive button.
	 * @return {@link Button}
	 */
	public Button getButton2() {
		return button2;
	}
	/**
	 * Gets the inactive state component.
	 * @return {@link Label}
	 */
	public Label getLabel1() {
		return label1;
	}
	/**
	 * Gets the clicked state component.
	 * @return {@link Label}
	 */
	public Label getLabel3() {
		return label3;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void handleMouseOver(final float x, final float y) {
		// floating over buttons 1
		if (super.isActive()) {
			if (label1.contains(x, y)) {
				if (enabled == null
						|| enabled != null
							&& enabled.passes()) {
					super.displayChild("2");
				}
				hovering = true;
			} else if (button2.contains(x, y)
					|| label3.contains(x, y)) {
				hovering = true;
			}
		}
		super.handleMouseOver(x, y);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void prepareForRendering() throws Exception {
		if (super.isVisible()
				&& super.getPosition() != null) {
			if (!hovering) {
				if (canStayOn3 == null
						|| canStayOn3 != null
								&& canStayOn3.passes()) {
					if (!label3.isVisible()) {
						displayChild("3");
					}
				} else {
					if (!label1.isVisible()) {
						displayChild("1");
					}
				}
			}
		}
		hovering = false;
		super.prepareForRendering();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setActive(final boolean isActive) {
		super.setActive(isActive);
		// switch active/inactive labels
		label1.setActive(isActive);
	}
	/**
	 * Sets the interactive button.
	 * @param newButton the {@link Button} to set
	 */
	public void setButton2(final Button newButton) {
		button2 = newButton;
		final ThreeStateButton me = this;
		button2.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				try {
					InputEvent.getInstance().addAction(
							me, // object
							me.getClass().getMethod(
									"displayChild", 
									new Class[] { String.class }
							),
							new String[] { "3" }
							);
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
		});
		super.addChild("2", button2);
	}
	/**
	 * Sets the {@link Condition} that determines when the
	 * {@link ThreeStateButton} can stay on the 3rd state without being hovered.
	 * @param c the {@link Condition} to set
	 */
	public void setCanStayOn3(final Condition c) {
		canStayOn3 = c;
	}
	/**
	 * Sets the {@link Condition} that determines when the
	 * {@link ThreeStateButton} is clickable. If the condition is null then the
	 * button is always clickable.
	 * @param c the {@link Condition} to set
	 */
	public void setEnabled(final Condition c) {
		enabled = c;
	}
	/**
	 * Sets the inactive label.
	 * @param newLabel the {@link label} to set
	 */
	public void setLabel1(final Label newLabel) {
		label1 = newLabel;
		super.addChild("1", label1);
	}
	/**
	 * Sets the active label.
	 * @param newLabel the {@link label} to set
	 */
	public void setLabel3(final Label newLabel) {
		label3 = newLabel;
		super.addChild("3", label3);
	}
}
